//
// Copyright (c) 2010 All Right Reserved
//
// vl
//
// 2010-05-01
// Contains ...
namespace LargoCommon.Music
{
using Abstract;
using JetBrains.Annotations;
using System;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.IO;
using System.Text;
using System.Xml.Linq;
///
/// Musical Header.
///
public class MusicalHeader
{
#region Fields
///
/// Musical metric.
///
private MusicalMetric metric;
///
/// Musical system.
///
private MusicalSystem system;
#endregion
#region Constructors
///
/// Initializes a new instance of the class.
///
public MusicalHeader() {
this.System = new MusicalSystem(); //// Needed !? (see MidiFileBridge!?)
this.Metric = new MusicalMetric(1, 0);
this.Tempo = DefaultValue.DefaultTempo;
this.Number = 1;
this.Origin = DateTime.Now;
this.Changed = DateTime.Now;
}
///
/// Initializes a new instance of the class.
///
/// The xml header.
public MusicalHeader(XElement xheader)
: this() {
Contract.Requires(xheader != null);
if (xheader == null) {
return;
}
this.Name = XmlSupport.ReadStringAttribute(xheader.Attribute("Name"));
this.Number = XmlSupport.ReadIntegerAttribute(xheader.Attribute("Number"));
this.FileName = XmlSupport.ReadStringAttribute(xheader.Attribute("FileName"));
//// this.FilePath = XmlSupport.ReadStringAttribute(xheader.Attribute("FilePath"));
var xorigin = xheader.Attribute("Origin");
this.Origin = xorigin != null ? XmlSupport.ReadDateTimeAttribute(xorigin) : DateTime.Now;
var xchanged = xheader.Attribute("Changed");
this.Changed = xorigin != null ? XmlSupport.ReadDateTimeAttribute(xchanged) : DateTime.Now;
this.System = new MusicalSystem(xheader.Element("System"));
this.Metric = new MusicalMetric(xheader.Element("Metric"));
this.Division = XmlSupport.ReadIntegerAttribute(xheader.Attribute("Division"));
this.Tempo = XmlSupport.ReadByteAttribute(xheader.Attribute("Tempo"));
this.NumberOfBars = XmlSupport.ReadIntegerAttribute(xheader.Attribute("NumberOfBars"));
this.NumberOfLines = XmlSupport.ReadIntegerAttribute(xheader.Attribute("NumberOfLines"));
this.NumberOfMelodicLines = XmlSupport.ReadByteAttribute(xheader.Attribute("NumberOfMelodicLines"));
this.NumberOfRhythmicLines = XmlSupport.ReadByteAttribute(xheader.Attribute("NumberOfRhythmicLines"));
}
#endregion
#region Static Properties
///
/// Gets the default musical header.
///
public static MusicalHeader GetDefaultMusicalHeader {
get {
var header = new MusicalHeader {
System = new MusicalSystem() {
RhythmicOrder = 24, //// 12
HarmonicOrder = DefaultValue.HarmonicOrder
},
Metric = new MusicalMetric(4, 2),
Division = 240
};
return header;
}
}
#endregion
#region Properties - Xml
///
/// Gets the get x element.
///
///
/// The get x element.
///
public XElement GetXElement {
get {
XElement xheader = new XElement("Header");
xheader.Add(new XAttribute("Name", this.Name ?? string.Empty));
xheader.Add(new XAttribute("Number", this.Number));
xheader.Add(new XAttribute("FileName", this.FileName ?? string.Empty));
//// xheader.Add(new XAttribute("FilePath", this.FilePath ?? string.Empty));
xheader.Add(new XAttribute("Origin", this.Origin ?? DateTime.Now));
xheader.Add(new XAttribute("Changed", this.Changed ?? DateTime.Now));
xheader.Add(this.System.GetXElement);
xheader.Add(this.Metric.GetXElement);
xheader.Add(new XAttribute("Division", this.Division));
xheader.Add(new XAttribute("Tempo", this.Tempo));
xheader.Add(new XAttribute("NumberOfBars", this.NumberOfBars));
xheader.Add(new XAttribute("NumberOfLines", this.NumberOfLines));
xheader.Add(new XAttribute("NumberOfMelodicLines", this.NumberOfMelodicLines));
xheader.Add(new XAttribute("NumberOfRhythmicLines", this.NumberOfRhythmicLines));
return xheader;
}
}
#endregion
#region Properties
/*
///
/// Gets or sets name of the collection.
///
/// Property description.
public string FilePath { get; set; }
*/
///
/// Gets or sets the name of the file.
///
///
/// The name of the file.
///
public string FileName { get; set; }
///
/// Gets or sets the origin.
///
///
/// The origin.
///
public DateTime? Origin { get; set; }
///
/// Gets or sets the changed.
///
///
/// The changed.
///
public DateTime? Changed { get; set; }
///
/// Gets or sets the name.
///
///
/// The name.
///
public string Name { get; set; }
///
/// Gets or sets the number.
///
///
/// The number.
///
public int Number { get; set; }
///
/// Gets the identifier.
///
///
/// The identifier.
///
public string Identifier => string.Format(CultureInfo.InvariantCulture, "{0}{1}", this.FileName, this.Name.ClearSpecialChars().Trim());
///
/// Gets the name of the two row.
///
///
/// The name of the two row.
///
[UsedImplicitly]
public string TwoRowName => string.Format(CultureInfo.InvariantCulture, "{0}\n{1}", this.FileName, this.NumberName);
///
/// Gets the name of the number.
///
///
/// The name of the number.
///
public string NumberName => string.Format(CultureInfo.InvariantCulture, "\t({0}) {1}", this.Number, this.Name.ClearSpecialChars().Trim());
/// Gets the name of the document file.
/// The name of the document file.
public string DocumentFileName => string.Format(CultureInfo.InvariantCulture, "{0}_{1}_{2}", this.FileName, this.Number, this.Name.ClearSpecialChars().Trim());
//// public string DocumentFileName => this.FileName;
///
/// Gets the rhythmic order.
///
///
/// The rhythmic order.
///
[UsedImplicitly]
public int Timing => this.System.RhythmicOrder / 8;
///
/// Gets or sets the metric.
///
///
/// The metric.
///
public MusicalMetric Metric {
get {
Contract.Ensures(Contract.Result() != null);
if (this.metric == null) {
throw new InvalidOperationException("Metric is null.");
}
return this.metric;
}
set => this.metric = value ?? throw new ArgumentException("Metric cannot be set null.", nameof(value));
}
///
/// Gets or sets the system.
///
///
/// The system.
///
public MusicalSystem System {
get {
Contract.Ensures(Contract.Result() != null);
if (this.system == null) {
throw new InvalidOperationException("System is null.");
}
return this.system;
}
set => this.system = value ?? throw new ArgumentException("System cannot be set null.", nameof(value));
}
///
/// Gets or sets the division.
///
///
/// The division.
///
public int Division { get; set; }
///
/// Gets or sets tempo.
///
/// Property description.
public int Tempo { get; set; }
///
/// Gets or sets NumberOfBars.
///
/// General musical property.
public int NumberOfBars { get; set; }
///
/// Gets or sets count of loaded parts.
///
/// General musical property.
/// Returns value.
public int NumberOfLines { get; set; }
///
/// Gets or sets NumberOfBars.
///
/// General musical property.
public byte NumberOfMelodicLines { get; set; }
///
/// Gets or sets NumberOfBars.
///
/// General musical property.
public byte NumberOfRhythmicLines { get; set; }
#endregion
#region String representation
/// String representation of the object.
/// Returns value.
public override string ToString() {
var s = new StringBuilder();
s.AppendFormat("Header {0} {1}", this.System, this.Metric);
return s.ToString();
}
#endregion
#region Public methods
/// Makes a deep copy of the MusicalHeader object.
/// Returns object.
public object Clone() {
var header = new MusicalHeader {
Name = this.Name,
Number = this.Number, //// 2019/02
FileName = this.FileName,
//// FilePath = this.FilePath,
System = this.System,
Metric = (MusicalMetric)this.Metric.Clone(),
Division = this.Division,
Tempo = this.Tempo,
NumberOfBars = this.NumberOfBars,
NumberOfLines = this.NumberOfLines
};
return header;
}
#endregion
}
}